<template>
  <el-collapse-item name="6">
    <template #title
      ><el-row align="middle" style="width: 100%">
        <el-col :span="4" style="text-align: start">
          <h2>OTA</h2>
        </el-col>
        <el-col :span="15">
          {{
            ota_status.state == 1
              ? "正在升级中......"
              : ota_status.state == 0
              ? ota_status.progress == 100
                ? "升级完成"
                : ""
              : ota_status.err_str
          }}
        </el-col>
        <el-col :span="4">
          <el-button
            :type="
              ota_status.state == 0 ? 'info' : ota_status.state < 0 ? 'danger' : 'success'
            "
            style="width: 20px; height: 20px; margin: auto 0"
            circle
          />
        </el-col>
      </el-row>
    </template>
    <div v-if="ota_status.state != 1">
      <div v-for="(item, idx) in config_list" :key="idx">
        <h3>{{ item.title }}</h3>
        <el-alert
          v-if="item.tips"
          v-for="(tips, idx) in item.tips"
          :key="tips.content + '_' + idx"
          :title="tips.content"
          :type="tips.type"
          show-icon
          :closable="false"
          style="letter-spacing: 2px"
        />
        <el-row
          v-for="(param, idx) in item.params"
          :key="item.title + '_' + idx"
          align="middle"
          style="margin-top: 20px"
        >
          <el-col :span="6">
            <b>{{ param.label }}</b>
          </el-col>
          <el-col :span="17">
            <el-input
              v-model="config.server.set_ota[param.key]"
              style="width: 100%"
              :placeholder="`请输入${param.label}`"
            />
          </el-col>
        </el-row>
        <el-button
          v-if="change"
          type="primary"
          round
          :loading="server_api.ticks?.ota_set_config > 0"
          @click="server_api.ota_set_config"
        >
          保存
        </el-button>
        <el-divider></el-divider>
        <el-button
          v-if="item.submit"
          v-for="(click, idx) in item.submit"
          :key="click.label + idx"
          type="primary"
          round
          :loading="click.loading ? click.loading : false"
          :disabled="click.disabled ? click.disabled : false"
          @click="click.onClick"
        >
          {{ click.label }}
        </el-button>
        <el-divider></el-divider>
      </div>
      <h3>文件上传</h3>
      <el-alert
        title="页面不支持回退, 可以直接刷旧页面"
        type="info"
        show-icon
        :closable="false"
        style="letter-spacing: 2px"
      />
      <el-upload
        style="margin-top: 5px"
        ref="upload"
        :limit="1"
        :on-exceed="handleExceed"
        :on-change="handleChange"
        :auto-upload="false"
        :show-file-list="false"
        accept=".bin"
      >
        <el-button :type="file.data ? 'warning' : 'primary'">{{
          file.data ? "更改文件" : "选择升级文件"
        }}</el-button>
        <template #tip>
          <el-tag type="warning" :style="'margin-top:0px;margin-left:0'">
            仅 BIN 文件
          </el-tag>
        </template>
      </el-upload>
      <p v-if="file.data">
        <el-tag type="success">{{ file.name }}</el-tag>
        <el-tag type="info" style="margin-left: 10px">{{
          size2str(file.data.size)
        }}</el-tag>
      </p>
      <el-button
        v-if="file.data && ota_file_type != 1"
        type="primary"
        round
        @click="server_api.ota_update_www_from_file(file.data)"
      >
        升级页面
      </el-button>
      <el-button
        v-if="file.data && ota_file_type != 2"
        type="primary"
        round
        @click="server_api.ota_update_app_from_file(file.data)"
      >
        升级固件
      </el-button>
      <el-button type="warning" round @click="server_api.ota_app_rollback()">
        固件回滚
      </el-button>
    </div>
    <div v-else>
      <el-progress type="circle" :percentage="ota_status.progress" />
    </div>
  </el-collapse-item>
</template>
<script setup lang="ts">
import store from "~/utils/store";
import server_api from "~/utils/server_api";
const config = toRef(store);
const ota_file_type = ref(0);
let task;
const change = computed(() => {
  return (
    JSON.stringify(config.value.server.ota) != JSON.stringify(config.value.server.set_ota)
  );
});

const ota_status = computed(() => {
  return config.value?.server?.ota_status;
});

function check_ota_status() {
  server_api.ota_get_status();
  if (ota_status.value.progress == 100 || ota_status.value.state < 0) {
    clearInterval(task);
    console.log("close task ", ota_status.value);
  }
}

function ota_start() {
  ota_status.value.progress = 0;
  ota_status.value.state = 0;
  task = setInterval(check_ota_status, 1000);
}

const config_list = computed(() => {
  let show_update_app = true;
  let show_update_www = true;
  if (ota_status.value.state == 1) {
    show_update_app = false;
    show_update_www = false;
  }
  return [
    {
      title: "服务器配置",
      tips: [
        {
          type: "info",
          content: "当版本URL存在时, 固件和WEB URL中的",
        },
        {
          type: "info",
          content: "${version} 会被替换为版本号, 否则去除",
        },
        {
          type: "info",
          content: "当版本URL为空时, 不会自动更新固件",
        },
        {
          type: "info",
          content: "由于页面没有版本控制,所以不会自动更新",
        },
        {
          type: "info",
          content: "版本/用户名/密码可以为空",
        },
      ],
      submit: [
        {
          label: "检查更新",
          onClick: server_api.refresh_ota_server_version,
          disabled: !config.value.server.set_ota.ver_url.length,
          loading: server_api.ticks?.refresh_ota_server_version > 0,
        },
        {
          label: config.value.server.set_ota.ver_url.length
            ? `从服务器升级固件(${config.value.server.ota.version})`
            : "从服务器升级固件",
          onClick: () => {
            server_api.ota_update_app_from_server();
            ota_start();
          },
          disabled:
            // (config.value.server.set_ota.ver_url.length
            //   ? Number(config.value.server.ota.version) <=
            //     Number(config.value.server.chip.version)
            //   : false) ||
            !config.value.server.set_ota.url.length && show_update_app,
        },
        {
          label: config.value.server.set_ota.ver_url.length
            ? `从服务器升级WEB(${config.value.server.ota.version})`
            : "从服务器升级WEB",
          onClick: () => {
            server_api.ota_update_www_from_server();
            ota_start();
          },
          disabled: !config.value.server.set_ota.web_url.length && show_update_www,
        },
      ],
      params: [
        {
          label: "固件获取URL",
          key: "url",
        },
        {
          label: "版本获取URL",
          key: "ver_url",
        },
        {
          label: "WEB获取URL",
          key: "web_url",
        },
        {
          label: "用户名",
          key: "user",
        },
        {
          label: "密码",
          key: "pwd",
        },
      ],
    },
  ];
});

import { genFileId } from "element-plus";
import type { UploadInstance, UploadProps, UploadRawFile } from "element-plus";
const upload = ref<UploadInstance>();
const file = ref<{ name: String; data: any }>({
  name: "",
  data: undefined,
});

function size2str(size: number) {
  if (size < 1024) {
    return size + " B";
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + " KB";
  } else if (size < 1024 * 1024 * 1024) {
    return (size / 1024 / 1024).toFixed(2) + " MB";
  } else {
    return (size / 1024 / 1024 / 1024).toFixed(2) + " GB";
  }
}

const handleExceed: UploadProps["onExceed"] = (files) => {
  const file = files[0] as UploadRawFile;
  upload.value!.clearFiles();
  file.uid = genFileId();
  upload.value!.handleStart(file);
};

const handleChange: UploadProps["onChange"] = (uploadFile) => {
  const reader = new FileReader();
  reader.onload = function (event) {
    const data = new Blob([event.target.result]);
    if (uploadFile.name.indexOf("app") != -1) ota_file_type.value = 1;
    else if (uploadFile.name.indexOf("www") != -1) ota_file_type.value = 2;
    else ota_file_type.value = 0;
    file.value.name = uploadFile.name;
    file.value.data = data;
  };
  reader.readAsArrayBuffer(uploadFile.raw);
};
</script>
<style scoped>
:deep(.el-button) {
  width: 90%;
  letter-spacing: 2px;
  margin: 10px auto;
}
</style>
